// Parts Copyright 2008 Newgrove Consultants Limited
// Modified By John Diss 
// From original work:
//
// Copyright 2006 - Ricardo Stuven (rstuven@gmail.com)
//
// This file is part of MsSqlSpatial.
// MsSqlSpatial is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// MsSqlSpatial is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public License
// along with MsSqlSpatial; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

using System.Data.SqlClient;
using System.Data.SqlTypes;
using GeoAPI.Coordinates;
using GeoAPI.Geometries;
using Microsoft.SqlServer.Server;
using MsSqlSpatial;

public partial class UserDefinedFunctions
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="table_name"></param>
    /// <param name="column_name"></param>
    /// <returns></returns>
    /// <example>
    /// </example>
    [SqlFunction(IsDeterministic = false, DataAccess = DataAccessKind.Read)]
    public static SqlBytes EnvelopeQuery(
        SqlString table_name,
        SqlString column_name)
    {
        return EnvelopeQueryWhere(table_name, column_name, SqlString.Null);
    }

    [SqlFunction(IsDeterministic = false, DataAccess = DataAccessKind.Read)]
    public static SqlBytes EnvelopeQueryWhere(
        SqlString table_name,
        SqlString column_name,
        SqlString condition)
    {
        using (SqlConnection connection = DatabaseHelper.ContextConnection)
        {
            connection.Open();
            using (SqlCommand command = connection.CreateCommand())
            {
                string tableName = table_name.Value;
                string columnName = column_name.Value;
                string schemaName = "";

                DatabaseHelper.SplitSchemaAndTableName(command, ref tableName, ref schemaName);
                int srid = GeometryColumnsTable.GetSRID(command, schemaName, tableName, columnName);

                string filterQuery = "";
                if (!condition.IsNull && condition.Value.Trim().Length != 0)
                    filterQuery = "WHERE " + condition.Value;

                DatabaseHelper.BuildCommand(command, string.Format(
                                                         @"SELECT 
  Min([{2}_Envelope_MinX])
, Max([{2}_Envelope_MaxX])
, Min([{2}_Envelope_MinY])
, Max([{2}_Envelope_MaxY])
FROM [{0}].[{1}]
{3}
"
                                                         , schemaName // {0}
                                                         , tableName // {1}
                                                         , columnName // {2}
                                                         , filterQuery // {3}
                                                         ));
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        if (reader.IsDBNull(0))
                            return SqlBytes.Null;
                        else
                        {
                            //IGeometry envelope = GeometryFactory<MsSqlCoordinate>.Default.ToGeometry(
                            //    new Envelope(
                            //      reader.GetDouble(0)
                            //    , reader.GetDouble(1)
                            //    , reader.GetDouble(2)
                            //    , reader.GetDouble(3)
                            //    ));

                            IGeometryFactory gf = Global.Services.GeometryFactory;
                            ICoordinateFactory cf = gf.CoordinateFactory;

                            IGeometry envelope =
                                gf.ToGeometry(
                                    gf.CreateExtents(
                                        cf.Create(
                                            reader.GetDouble(0),
                                            reader.GetDouble(1))
                                        , cf.Create(
                                              reader.GetDouble(2),
                                              reader.GetDouble(3))
                                        ));
                            return ConvertGeometry.ToSqlBytes(envelope, srid);
                        }
                    }
                }
            }
        }

        return SqlBytes.Null;
    }
} ;